0809. 情感丰富的文字【中等】
1. 📝 题目描述
有时候人们会用重复写一些字母来表示额外的感受,比如 "hello" -> "heeellooo", "hi" -> "hiii"。我们将相邻字母都相同的一串字符定义为相同字母组,例如:"h", "eee", "ll", "ooo"。
对于一个给定的字符串 S,如果另一个单词能够通过将一些字母组扩张从而使其和 S 相同,我们将这个单词定义为可扩张的(stretchy)。扩张操作定义如下:选择一个字母组(包含字母 c ),然后往其中添加相同的字母 c 使其长度达到 3 或以上。
例如,以 "hello" 为例,我们可以对字母组 "o" 扩张得到 "hellooo",但是无法以同样的方法得到 "helloo" 因为字母组 "oo" 长度小于 3。此外,我们可以进行另一种扩张 "ll" -> "lllll" 以获得 "helllllooo"。如果 s = "helllllooo",那么查询词 "hello" 是可扩张的,因为可以对它执行这两种扩张操作使得 query = "hello" -> "hellooo" -> "helllllooo" = s。
输入一组查询单词,输出其中可扩张的单词数量。
示例:
txt
输入:
s = "heeellooo"
words = ["hello", "hi", "helo"]
输出:1
解释:
我们能通过扩张 "hello" 的 "e" 和 "o" 来得到 "heeellooo"。
我们不能通过扩张 "helo" 来得到 "heeellooo" 因为 "ll" 的长度小于 3。1
2
3
4
5
6
7
2
3
4
5
6
7
提示:
1 <= s.length, words.length <= 1001 <= words[i].length <= 100- s 和所有在
words中的单词都只由小写字母组成。
2. 🎯 s.1 - 双指针
c
bool isStretchy(char* s, char* word) {
int i = 0, j = 0, n = strlen(s), m = strlen(word);
while (i < n && j < m) {
if (s[i] != word[j]) return false;
int lenS = 1, lenW = 1;
while (i + lenS < n && s[i + lenS] == s[i]) lenS++;
while (j + lenW < m && word[j + lenW] == word[j]) lenW++;
if (lenS < lenW || (lenS > lenW && lenS < 3)) return false;
i += lenS; j += lenW;
}
return i == n && j == m;
}
int expressiveWords(char* s, char** words, int wordsSize) {
int res = 0;
for (int i = 0; i < wordsSize; i++)
if (isStretchy(s, words[i])) res++;
return res;
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
js
/**
* @param {string} s
* @param {string[]} words
* @return {number}
*/
var expressiveWords = function (s, words) {
let res = 0
for (const word of words) {
if (isStretchy(s, word)) res++
}
return res
}
function isStretchy(s, word) {
let i = 0,
j = 0
while (i < s.length && j < word.length) {
if (s[i] !== word[j]) return false
let lenS = 1,
lenW = 1
while (i + lenS < s.length && s[i + lenS] === s[i]) lenS++
while (j + lenW < word.length && word[j + lenW] === word[j]) lenW++
if (lenS < lenW || (lenS > lenW && lenS < 3)) return false
i += lenS
j += lenW
}
return i === s.length && j === word.length
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
py
class Solution:
def expressiveWords(self, s: str, words: List[str]) -> int:
def is_stretchy(word: str) -> bool:
i = j = 0
while i < len(s) and j < len(word):
if s[i] != word[j]: return False
len_s = len_w = 1
while i + len_s < len(s) and s[i + len_s] == s[i]: len_s += 1
while j + len_w < len(word) and word[j + len_w] == word[j]: len_w += 1
if len_s < len_w or (len_s > len_w and len_s < 3): return False
i += len_s; j += len_w
return i == len(s) and j == len(word)
return sum(1 for w in words if is_stretchy(w))1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
- 时间复杂度:
,其中 m 是单词数,n 是 s 长度,k 是单词平均长度 - 空间复杂度:
算法思路:
- 对每个单词,用双指针分组比较连续相同字符的长度
- 若组长度相等则匹配;若 s 的组更长且长度 >= 3 则可扩展;否则不匹配